#include <gtest/gtest.h>
#include <fstream>
#include "rtdev/safetyboard/scbitf.h"
#include "rtbus/rtbus.h"

using rtdev::SafetyBoardItf;

class PScbConfigFile : public ::testing::Test
{
public:
    virtual void SetUp() override {}
    virtual void TearDown() override { std::remove(cfgfile.c_str()); }
    void load_config_sim()
    {
        std::string cfg = R"(
<?xml version="1.0" encoding="UTF-8"?>
<cab>
    <info name="MiniCab" type="3" sim="1"/>
    <bus chn="0"/>
</cab>
        )";
        std::ofstream ofs(cfgfile);
        ofs << cfg;
        ofs.close();
    }
    void load_config_real()
    {
        std::string cfg = R"(
<?xml version="1.0" encoding="UTF-8"?>
<cab>
    <info name="MiniCab" type="3" sim="0"/>
    <bus chn="0"/>
</cab>
        )";
        std::ofstream ofs(cfgfile);
        ofs << cfg;
        ofs.close();
    }
    std::string cfgfile = "/tmp/minicab.xml";
};
TEST_F(PScbConfigFile, create_sim)
{
    auto pscb = SafetyBoardItf::create(rtdev::kScbTypeMinicab);
    EXPECT_TRUE(pscb != nullptr);
    load_config_sim();
    ASSERT_EQ(pscb->init(cfgfile.c_str()), 0);
    ASSERT_EQ(pscb->is_sim(), true);
    EXPECT_EQ(pscb->cab()->get_hw_ver(), 0xffffff);
    EXPECT_EQ(pscb->cab()->get_sw_ver(), 0xffffff);
    EXPECT_STREQ(pscb->cab()->get_version_str().c_str(), "MiniCab HW:0.0.0S SW:0.0.0S");
    pscb->get_recv_data();
    pscb->set_send_data();
    EXPECT_TRUE(pscb->is_alive());
}

TEST_F(PScbConfigFile, create_real)
{
    auto pscb = SafetyBoardItf::create(rtdev::kScbTypeMinicab);
    EXPECT_TRUE(pscb != nullptr);
    load_config_real();
    ASSERT_EQ(pscb->init(cfgfile.c_str()), 0);
    ASSERT_EQ(pscb->is_sim(), false);
    EXPECT_EQ(pscb->cab()->get_hw_ver(), 0);
    EXPECT_EQ(pscb->cab()->get_sw_ver(), 0);
    EXPECT_STREQ(pscb->name(), "MiniCab");
    EXPECT_STREQ(pscb->cab()->get_version_str().c_str(), "MiniCab HW:0.0.0 SW:0.0.0");
    pscb->get_recv_data();
    pscb->set_send_data();
    EXPECT_FALSE(pscb->is_alive());
}

class PScbRealTest : public ::testing::Test
{
public:
    virtual void SetUp() override
    {
        load_config();
        pscb.reset(SafetyBoardItf::create(rtdev::kScbTypeMinicab));
        if (pscb->init(cfgfile.c_str()) != 0)
        {
            throw std::runtime_error("init failed");
        }
    }
    virtual void TearDown() override { std::remove(cfgfile.c_str()); }

    void load_config()
    {
        std::string cfg = R"(
<?xml version="1.0" encoding="UTF-8"?>
<cab>
    <info name="MiniCab" type="3" sim="0"/>
    <bus chn="0"/>
</cab>
        )";
        std::ofstream ofs(cfgfile);
        ofs << cfg;
        ofs.close();
    }
    std::string cfgfile = "/tmp/minicab.xml";
    std::shared_ptr<SafetyBoardItf> pscb;
};
TEST_F(PScbRealTest, boot) { pscb->boot(); }